namespace C1.Win.C1FlexGrid
{
    using C1.Util;
    using C1.Win.C1FlexGrid.Util.Styles;
    using System;
    using System.Drawing;
    using System.Windows.Forms;

    internal class GridEditHandler
    {
        internal int _col;
        internal IGridEditor _comboBox;
        internal IGridEditor _editor;
        internal int _row;
        internal IGridEditor _textBox;
        internal C1FlexGridBase _view;

        internal GridEditHandler(C1FlexGridBase view)
        {
            this._view = view;
        }

        internal virtual bool CreateEditor(int row, int col)
        {
            EditorTypeEnum editorType = this.GetEditorType(row, col);
            if (editorType == EditorTypeEnum.None)
            {
                return false;
            }
            this.FinishEditing(false);
            this._view._mouseHandler.ResetMouse();
            switch (editorType)
            {
                case EditorTypeEnum.TextBox:
                case EditorTypeEnum.PopEdit:
                    if (this._textBox == null)
                    {
                        Control control = new GridEditorTextBox(this._view);
                        control.Visible = false;
                        this._view.Controls.Add(control);
                        control.LostFocus += new EventHandler(this.Editor_LostFocus);
                        this._textBox = (IGridEditor) control;
                    }
                    this._editor = this._textBox;
                    break;

                case EditorTypeEnum.DropDown:
                    if (this._comboBox == null)
                    {
                        Control control2 = new GridEditorComboBox(this._view);
                        control2.Visible = false;
                        this._view.Controls.Add(control2);
                        control2.LostFocus += new EventHandler(this.Editor_LostFocus);
                        this._comboBox = (IGridEditor) control2;
                    }
                    this._editor = this._comboBox;
                    break;
            }
            this._row = row;
            this._col = col;
            return (this._editor != null);
        }

        internal void Editor_LostFocus(object sender, EventArgs e)
        {
            Control control = this._editor as Control;
            if ((control != null) && !control.Focused)
            {
                this.FinishEditing(false);
            }
        }

        internal bool FinishEditing(bool cancel)
        {
            if (this.IsActive())
            {
                if (this._view._grid.IsBadRowCol(this._row, this._col))
                {
                    cancel = true;
                }
                Control control = (Control) this._editor;
                if (!cancel && this._view.OnValidateEdit(this._row, this._col, this._editor.IsValid()))
                {
                    this._view.ShowCell(this._row, this._col);
                    control.Focus();
                    return false;
                }
                object content = this._editor.GetContent();
                this._editor = null;
                if (control.Focused)
                {
                    control.Visible = false;
                    this._view.Focus();
                }
                if (!this._view.Focused && this._view._grid.IsDataBound())
                {
                    this._view._grid._dataSource.OnLostFocus();
                }
                control.Visible = false;
                if (!cancel)
                {
                    this._view.SetData(this._row, this._col, content, true);
                    this._view.OnAfterEdit(this._row, this._col);
                }
            }
            return true;
        }

        internal virtual Rectangle GetButtonRect(Rectangle rc)
        {
            int verticalScrollBarWidth = C1.Util.SystemInformation.VerticalScrollBarWidth;
            Rectangle rectangle = new Rectangle(0, rc.Y, 0, rc.Height);
            if ((rc.Width > verticalScrollBarWidth) && (rc.Height > 5))
            {
                rectangle.Width = verticalScrollBarWidth;
                rectangle.X = rc.Right - rectangle.Width;
            }
            return rectangle;
        }

        internal EditorTypeEnum GetEditorType(int row, int col)
        {
            if (!this._view.IsCellFixed(row, col))
            {
                if (this._view.GetCellCheck(row, col) != CheckEnum.None)
                {
                    return EditorTypeEnum.Checkbox;
                }
                string cellComboList = this._view._grid.GetCellComboList(row, col);
                if ((cellComboList != null) && (cellComboList.Length > 0))
                {
                    if (cellComboList == "...")
                    {
                        return EditorTypeEnum.PopUp;
                    }
                    if (cellComboList == "|...")
                    {
                        return EditorTypeEnum.PopEdit;
                    }
                    return EditorTypeEnum.DropDown;
                }
                if (this._view._grid.GetCellDataMap(row, col) != null)
                {
                    return EditorTypeEnum.DropDown;
                }
                Type cellDataType = this._view._grid.GetCellDataType(row, col);
                if ((cellDataType != null) && cellDataType.IsEnum)
                {
                    return EditorTypeEnum.DropDown;
                }
                if ((this._view._grid.GetCellDataType(row, col) == typeof(bool)) && (this._view._grid.GetCellFormat(row, col) != null))
                {
                    return EditorTypeEnum.ToggleText;
                }
            }
            return EditorTypeEnum.TextBox;
        }

        internal bool IsActive()
        {
            return (this._editor != null);
        }

        internal bool StartEditing(int row, int col, char key)
        {
            return this.StartEditing(row, col, key, false);
        }

        internal bool StartEditing(int row, int col, char key, bool force)
        {
            bool flag = this._view.CanStartEdit(row, col);
            if (!force && !flag)
            {
                return false;
            }
            if (this._view._showButtons == ShowButtonsEnum.WhenEditing)
            {
                this._view.Invalidate(row, col);
            }
            EditorTypeEnum editorType = this.GetEditorType(row, col);
            if (editorType == EditorTypeEnum.Checkbox)
            {
                if ((key != ' ') && (key != '\r'))
                {
                    return false;
                }
                if (this._view.OnStartEdit(row, col))
                {
                    return false;
                }
                if (this._view.OnValidateEdit(row, col))
                {
                    return false;
                }
                this._view.ToggleCellCheck(row, col, true);
                this._view.OnAfterEdit(row, col);
                return true;
            }
            if ((editorType == EditorTypeEnum.PopUp) && (key <= ' '))
            {
                if (this._view.OnStartEdit(row, col))
                {
                    return false;
                }
                this._view.OnCellButtonClick(row, col);
                this._view.OnAfterEdit(row, col);
                return true;
            }
            if (editorType == EditorTypeEnum.ToggleText)
            {
                return this.ToggleText(row, col, key);
            }
            if (this._view.OnStartEdit(row, col))
            {
                return false;
            }
            if (!this.CreateEditor(row, col))
            {
                return false;
            }
            this._editor.StartEditing(row, col, key);
            return true;
        }

        internal bool StartEditing(int row, int col, Point ptMouse, bool dblClick)
        {
            if (this._view.Editor == null)
            {
                if (!this._view.CanStartEdit(row, col))
                {
                    return false;
                }
                if (this._view._showButtons == ShowButtonsEnum.WhenEditing)
                {
                    this._view.Invalidate(row, col);
                }
                if (!this._view.Selection.Contains(row, col))
                {
                    this._view.Select(row, col, false);
                }
                EditorTypeEnum editorType = this.GetEditorType(row, col);
                Rectangle cellRectDisplay = this._view.GetCellRectDisplay(row, col);
                if (dblClick)
                {
                    switch (editorType)
                    {
                        case EditorTypeEnum.Checkbox:
                            return false;

                        case EditorTypeEnum.ToggleText:
                            return this.ToggleText(row, col, ' ');
                    }
                    if (this._view.OnStartEdit(row, col))
                    {
                        return false;
                    }
                    if (!this.CreateEditor(row, col))
                    {
                        return false;
                    }
                    this._editor.StartEditing(row, col, ptMouse, dblClick);
                    return true;
                }
                switch (editorType)
                {
                    case EditorTypeEnum.DropDown:
                        if (this.GetButtonRect(cellRectDisplay).Contains(ptMouse.X, ptMouse.Y))
                        {
                            if (this._view.OnStartEdit(row, col))
                            {
                                return false;
                            }
                            if (!this.CreateEditor(row, col))
                            {
                                return false;
                            }
                            this._editor.StartEditing(row, col, ptMouse, dblClick);
                            return true;
                        }
                        return false;

                    case EditorTypeEnum.PopUp:
                    case EditorTypeEnum.PopEdit:
                        if (this.GetButtonRect(cellRectDisplay).Contains(ptMouse.X, ptMouse.Y))
                        {
                            if (this._view.OnStartEdit(row, col))
                            {
                                return false;
                            }
                            this._view.OnCellButtonClick(row, col);
                            this._view.OnAfterEdit(row, col);
                            return true;
                        }
                        return false;

                    case EditorTypeEnum.Checkbox:
                    {
                        Style styleDisplay = this._view.GetStyleDisplay(row, col);
                        if (this._view.GetCheckRect(row, col, styleDisplay, cellRectDisplay).Contains(ptMouse.X, ptMouse.Y))
                        {
                            if (this._view.OnStartEdit(row, col))
                            {
                                return false;
                            }
                            if (this._view.OnValidateEdit(row, col))
                            {
                                return false;
                            }
                            this._view.ToggleCellCheck(row, col, true);
                            this._view.OnAfterEdit(row, col);
                            return true;
                        }
                        return false;
                    }
                }
            }
            return false;
        }

        internal bool ToggleText(int row, int col, char key)
        {
            if ((key != ' ') && (key != '\r'))
            {
                return false;
            }
            if (this._view.OnStartEdit(row, col))
            {
                return false;
            }
            if (this._view.OnValidateEdit(row, col))
            {
                return false;
            }
            object data = this._view.GetData(row, col);
            if ((data == null) || !(data is bool))
            {
                data = false;
            }
            this._view.SetData(row, col, !((bool) data));
            this._view.OnAfterEdit(row, col);
            return true;
        }

        internal void UpdatePosition()
        {
            if (this._editor != null)
            {
                this._editor.UpdatePosition();
            }
        }
    }
}

